# 客户端
import wx
from socket import *
import threading  # 多线程

class MyFrame(wx.Frame):
    def __init__(self, name):
        super().__init__(None, title = f'聊天室-客户端【{name}】',
                         size = (450, 670), pos = (0, 50))
        self.name = name  # 客户端名称
        self.is_connected = False  # 表示连接状态
        # 服务端界面
        panel = wx.Panel(self)
        conn_btn = wx.Button(panel, label = '进入聊天室',
                                     size = (200, 40), pos = (10, 10))
        dis_conn_btn = wx.Button(panel, label='离开聊天室',
                                     size = (200, 40), pos = (220, 10))
        # 显示当前的聊天信息，只读
        self.message_text = wx.TextCtrl(panel, size = (410, 400), pos = (10, 60),
                    style = wx.TE_MULTILINE | wx.TE_READONLY)
        # 信息输入框
        self.input_text = wx.TextCtrl(panel, size = (410, 100), pos = (10, 470),
                                 style = wx.TE_MULTILINE)
        clear_btn = wx.Button(panel, label='清空',
                                     size = (200, 40), pos = (10, 580))
        send_btn = wx.Button(panel, label='发送',
                                     size = (200, 40), pos = (220, 580))
        # 绑定事件方法
        conn_btn.Bind(wx.EVT_BUTTON, self.conn)
        dis_conn_btn.Bind(wx.EVT_BUTTON, self.dis_conn)
        clear_btn.Bind(wx.EVT_BUTTON, self.clear_text)
        send_btn.Bind(wx.EVT_BUTTON, self.send_msg)
        self.Show()

    # 加入
    def conn(self, event):
        print('加入聊天室...')
        if not self.is_connected:
            # 修改状态为已连接
            self.is_connected = True
            # 创建客户端socket
            self.client_socket = socket()
            # 建立连接
            self.client_socket.connect(('127.0.0.1', 8888))
            # 发送客户端名称
            self.client_socket.send(self.name.encode('utf-8'))
            # 接收服务端的回复，直接在线程中接收
            # msg = self.client_socket.recv(1024).decode('utf-8')  # 等待
            # self.message_text.AppendText(msg)
            # 守护线程：开启循环接收服务端的消息
            main_thread = threading.Thread(target=self.recv_msg, daemon=True)
            # 启动
            main_thread.start()
        else:
            wx.MessageBox('您已经加入聊天室了~', '提示', wx.OK | wx.ICON_QUESTION)

    # 接收服务端的群发消息
    def recv_msg(self):
        print('接收服务端消息...')  # 最后一次离线消息接收不到
        while self.is_connected:
            msg = self.client_socket.recv(1024).decode('utf-8')  # 等待
            self.message_text.AppendText(msg + '\n')

    # 离开
    def dis_conn(self, event):
        print('离开聊天室...')
        # 通知服务端，移除你的聊天线程，发送一个特殊的消息
        self.client_socket.send((self.name + '下线了').encode('utf-8'))
        # 修改连接状态
        self.is_connected = False

    # 清空
    def clear_text(self, event):
        print('清空消息输入框...')

    # 发送
    def send_msg(self, event):
        print('发送消息...')
        if self.is_connected:
            # 获取输入框的消息内容
            msg = self.input_text.GetValue()
            if msg.strip() != '':
                # 发送
                self.client_socket.send(msg.encode('utf-8'))
                # 清空输入框
                self.input_text.Clear()
            else:
                wx.MessageBox('您还没有输入内容~', '提示', wx.OK | wx.ICON_QUESTION)
            # 接收本次回复，能不能收到客户端发的别人的消息？不能？需要把接收服务端消息做成一个独立的任务
            # recv_msg = self.client_socket.recv(1024).decode('utf-8')
            # self.message_text.AppendText(recv_msg)
        else:
            wx.MessageBox('您还没有加入聊天室~', '提示', wx.OK | wx.ICON_QUESTION)

if __name__ == '__main__':
    app = wx.App()
    frame = MyFrame('李四')
    app.MainLoop()